{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[![xeus-cling](images/xeus-cling.png)](https://github.com/jupyter-xeus/xeus-cling/)\n",
    "\n",
    "A Jupyter kernel for C++ based on the `cling` C++ interpreter and the `xeus` native implementation of the Jupyter protocol, xeus.\n",
    "\n",
    "- GitHub repository: https://github.com/jupyter-xeus/xeus-cling/\n",
    "- Online documentation: https://xeus-cling.readthedocs.io/"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Usage\n",
    "\n",
    "<div style=\"background: #efffed;\n",
    "            border: 1px solid grey;\n",
    "            margin: 8px 0 8px 0;\n",
    "            text-align: center;\n",
    "            padding: 8px; \">\n",
    "    <i class=\"fa-play fa\" \n",
    "       style=\"font-size: 40px;\n",
    "              line-height: 40px;\n",
    "              margin: 8px;\n",
    "              color: #444;\">\n",
    "    </i>\n",
    "    <div>\n",
    "    To run the selected code cell, hit <pre style=\"background: #efffed\">Shift + Enter</pre>\n",
    "    </div>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Output and error streams\n",
    "\n",
    "`std::cout` and `std::cerr` are redirected to the notebook frontend."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <iostream>\n",
    "\n",
    "std::cout << \"some output\" << std::endl;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "std::cerr << \"some error\" << std::endl;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <stdexcept>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "throw std::runtime_error(\"Unknown exception\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Omitting the `;` in the last statement of a cell results in an output being printed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "int j = 5;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "j"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Interpreting the C++ programming language\n",
    "\n",
    "`cling` has a broad support of the features of C++. You can define functions, classes, templates, etc ..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "double sqr(double a)\n",
    "{\n",
    "    return a * a;\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "double a = 2.5;\n",
    "double asqr = sqr(a);\n",
    "asqr"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Classes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Foo\n",
    "{\n",
    "public:\n",
    "\n",
    "    virtual ~Foo() {}\n",
    "    \n",
    "    virtual void print(double value) const\n",
    "    {\n",
    "        std::cout << \"Foo value = \" << value << std::endl;\n",
    "    }\n",
    "};"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Foo bar;\n",
    "bar.print(1.2);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Polymorphism"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Bar : public Foo\n",
    "{\n",
    "public:\n",
    "\n",
    "    virtual ~Bar() {}\n",
    "    \n",
    "    virtual void print(double value) const\n",
    "    {\n",
    "        std::cout << \"Bar value = \" << 2 * value << std::endl;\n",
    "    }\n",
    "};"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Foo* bar2 = new Bar;\n",
    "bar2->print(1.2);\n",
    "delete bar2;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Templates"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <typeinfo>\n",
    "\n",
    "template <class T>\n",
    "class FooT\n",
    "{\n",
    "public:\n",
    "    \n",
    "    explicit FooT(const T& t) : m_t(t) {}\n",
    "    \n",
    "    void print() const\n",
    "    {\n",
    "        std::cout << typeid(T).name() << \" m_t = \" << m_t << std::endl;\n",
    "    }\n",
    "    \n",
    "private:\n",
    "    \n",
    "    T m_t;\n",
    "};"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "FooT<double> foot(1.2);\n",
    "foot.print();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## C++11 / C++14 support"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Foo11\n",
    "{\n",
    "public:\n",
    "    \n",
    "    Foo11() { std::cout << \"Foo11 default constructor\" << std::endl; }\n",
    "    Foo11(const Foo11&) { std::cout << \"Foo11 copy constructor\" << std::endl; }\n",
    "    Foo11(Foo11&&) { std::cout << \"Foo11 move constructor\" << std::endl; }\n",
    "};"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Foo11 f1;\n",
    "Foo11 f2(f1);\n",
    "Foo11 f3(std::move(f1));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <vector>\n",
    "\n",
    "std::vector<int> v = { 1, 2, 3};\n",
    "auto iter = ++v.begin();\n",
    "v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "*iter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "... and also lambda, universal references, `decltype`, etc ..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Documentation and completion\n",
    "\n",
    " - Documentation for types of the standard library is retrieved on cppreference.com.\n",
    " - The quick-help feature can also be enabled for user-defined types and third-party libraries. More documentation on this feature is available at https://xeus-cling.readthedocs.io/en/latest/inline_help.html.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "?std::vector"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Using the `display_data` mechanism"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For a user-defined type `T`, the rich rendering in the notebook and JupyterLab can be enabled by by implementing the function `nl::json mime_bundle_repr(const T& im)`, which returns the JSON mime bundle for that type.\n",
    "\n",
    "More documentation on the rich display system of Jupyter and Xeus-cling is available at https://xeus-cling.readthedocs.io/en/latest/rich_display.html"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Image example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <string>\n",
    "#include <fstream>\n",
    "\n",
    "#include \"nlohmann/json.hpp\"\n",
    "\n",
    "#include \"xtl/xbase64.hpp\"\n",
    "\n",
    "namespace nl = nlohmann;\n",
    "\n",
    "namespace im\n",
    "{\n",
    "    struct image\n",
    "    {   \n",
    "        inline image(const std::string& filename)\n",
    "        {\n",
    "            std::ifstream fin(filename, std::ios::binary);   \n",
    "            m_buffer << fin.rdbuf();\n",
    "        }\n",
    "        \n",
    "        std::stringstream m_buffer;\n",
    "    };\n",
    "    \n",
    "    nl::json mime_bundle_repr(const image& i)\n",
    "    {\n",
    "        auto bundle = nl::json::object();\n",
    "        bundle[\"image/png\"] = xtl::base64encode(i.m_buffer.str());\n",
    "        return bundle;\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im::image marie(\"images/marie.png\");\n",
    "marie"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Audio example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <string>\n",
    "#include <fstream>\n",
    "\n",
    "#include \"nlohmann/json.hpp\"\n",
    "\n",
    "#include \"xtl/xbase64.hpp\"\n",
    "\n",
    "namespace nl = nlohmann;\n",
    "\n",
    "namespace au\n",
    "{\n",
    "    struct audio\n",
    "    {   \n",
    "        inline audio(const std::string& filename)\n",
    "        {\n",
    "            std::ifstream fin(filename, std::ios::binary);   \n",
    "            m_buffer << fin.rdbuf();\n",
    "        }\n",
    "        \n",
    "        std::stringstream m_buffer;\n",
    "    };\n",
    "    \n",
    "    nl::json mime_bundle_repr(const audio& a)\n",
    "    {\n",
    "        auto bundle = nl::json::object();\n",
    "        bundle[\"text/html\"] =\n",
    "           std::string(\"<audio controls=\\\"controls\\\"><source src=\\\"data:audio/wav;base64,\")\n",
    "           + xtl::base64encode(a.m_buffer.str()) +\n",
    "            \"\\\" type=\\\"audio/wav\\\" /></audio>\";\n",
    "        return bundle;\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "au::audio drums(\"audio/audio.wav\");\n",
    "drums"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Display"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include \"xcpp/xdisplay.hpp\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xcpp::display(drums);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Update-display"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <string>\n",
    "#include \"xcpp/xdisplay.hpp\"\n",
    "\n",
    "#include \"nlohmann/json.hpp\"\n",
    "\n",
    "namespace nl = nlohmann;\n",
    "\n",
    "namespace ht\n",
    "{\n",
    "    struct html\n",
    "    {   \n",
    "        inline html(const std::string& content)\n",
    "        {\n",
    "            m_content = content;\n",
    "        }\n",
    "        std::string m_content;\n",
    "    };\n",
    "\n",
    "    nl::json mime_bundle_repr(const html& a)\n",
    "    {\n",
    "        auto bundle = nl::json::object();\n",
    "        bundle[\"text/html\"] = a.m_content;\n",
    "        return bundle;\n",
    "    }\n",
    "}\n",
    "\n",
    "// A blue rectangle\n",
    "ht::html rect(R\"(\n",
    "<div style='\n",
    "    width: 90px;\n",
    "    height: 50px;\n",
    "    line-height: 50px;\n",
    "    background-color: blue;\n",
    "    color: white;\n",
    "    text-align: center;'>\n",
    "Original\n",
    "</div>)\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xcpp::display(rect, \"some_display_id\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "// Update the rectangle to be red\n",
    "rect.m_content = R\"(\n",
    "<div style='\n",
    "    width: 90px;\n",
    "    height: 50px;\n",
    "    line-height: 50px;\n",
    "    background-color: red;\n",
    "    color: white;\n",
    "    text-align: center;'>\n",
    "Updated\n",
    "</div>)\";\n",
    "\n",
    "xcpp::display(rect, \"some_display_id\", true);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Clear output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <chrono>\n",
    "#include <iostream>\n",
    "#include <thread>\n",
    "\n",
    "#include \"xcpp/xdisplay.hpp\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "std::cout << \"hello\" << std::endl;\n",
    "std::this_thread::sleep_for(std::chrono::seconds(1));\n",
    "xcpp::clear_output();  // will flicker when replacing \"hello\" with \"goodbye\"\n",
    "std::this_thread::sleep_for(std::chrono::seconds(1));\n",
    "std::cout << \"goodbye\" << std::endl;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "std::cout << \"hello\" << std::endl;\n",
    "std::this_thread::sleep_for(std::chrono::seconds(1));\n",
    "xcpp::clear_output(true);  // prevents flickering\n",
    "std::this_thread::sleep_for(std::chrono::seconds(1));\n",
    "std::cout << \"goodbye\" << std::endl;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Magics\n",
    "\n",
    "Magics are special commands for the kernel that are not part of the C++ language.\n",
    "\n",
    "They are defined with the symbol `%` for a line magic and `%%` for a cell magic.\n",
    "\n",
    "More documentation for magics is available at https://xeus-cling.readthedocs.io/en/latest/magics.html."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <algorithm>\n",
    "#include <vector>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "std::vector<double> to_shuffle = {1, 2, 3, 4};"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%timeit std::random_shuffle(to_shuffle.begin(), to_shuffle.end());"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[![xtensor](images/xtensor.png)](https://github.com/xtensor-stack/xtensor/)\n",
    "\n",
    "- GitHub repository: https://github.com/xtensor-stack/xtensor/\n",
    "- Online documentation: https://xtensor.readthedocs.io/\n",
    "- NumPy to xtensor cheat sheet: http://xtensor.readthedocs.io/en/latest/numpy.html\n",
    "\n",
    "`xtensor` is a C++ library for manipulating N-D arrays with an API very similar to that of numpy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <iostream>\n",
    "\n",
    "#include \"xtensor/xarray.hpp\"\n",
    "#include \"xtensor/xio.hpp\"\n",
    "#include \"xtensor/xview.hpp\"\n",
    "\n",
    "xt::xarray<double> arr1\n",
    "  {{1.0, 2.0, 3.0},\n",
    "   {2.0, 5.0, 7.0},\n",
    "   {2.0, 5.0, 7.0}};\n",
    "\n",
    "xt::xarray<double> arr2\n",
    "  {5.0, 6.0, 7.0};\n",
    "\n",
    "xt::view(arr1, 1) + arr2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Together with the C++ Jupyter kernel, `xtensor` offers a similar experience as `NumPy` in the Python Jupyter kernel, including broadcasting and universal functions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <iostream>\n",
    "#include \"xtensor/xarray.hpp\"\n",
    "#include \"xtensor/xio.hpp\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xt::xarray<int> arr\n",
    "  {1, 2, 3, 4, 5, 6, 7, 8, 9};\n",
    "\n",
    "arr.reshape({3, 3});\n",
    "\n",
    "std::cout << arr;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include \"xtensor-blas/xlinalg.hpp\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xt::xtensor<double, 2> m = {{1.5, 0.5}, {0.7, 1.0}};\n",
    "std::cout << \"Matrix rank: \" << std::endl << xt::linalg::matrix_rank(m) << std::endl;\n",
    "std::cout << \"Matrix inverse: \" << std::endl << xt::linalg::inv(m) << std::endl;\n",
    "std::cout << \"Eigen values: \" << std::endl << xt::linalg::eigvals(m) << std::endl;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xt::xarray<double> arg1 = xt::arange<double>(9);\n",
    "xt::xarray<double> arg2 = xt::arange<double>(18);\n",
    "\n",
    "arg1.reshape({3, 3});\n",
    "arg2.reshape({2, 3, 3});\n",
    "\n",
    "std::cout << xt::linalg::dot(arg1, arg2) << std::endl;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++14",
   "language": "C++14",
   "name": "xcpp14"
  },
  "language_info": {
   "codemirror_mode": "text/x-c++src",
   "file_extension": ".cpp",
   "mimetype": "text/x-c++src",
   "name": "c++",
   "version": "14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
